/*Hm9gUKDDwtNjV7Mk8onAzgXlk2sN3YqGeiNBfMPmEAaQ5tb/cjXQzjs3lVWuDzNj*/
import {ajax, toast} from 'nc-lightapp-front';
import constants from '../constants';
import {dataSource, allTransferPageCode} from '../../source/constants';

import ampub from 'ampub';
import fa from 'fa';

const {components, utils} = ampub;
const {fa_utils} = fa;

const {getContext, loginContextKeys} = components.LoginContext;
const {showMessage, MsgConst, showConfirm, showErrorMessageByRes} = utils.msgUtils;
const {getMultiLangByID} = utils.multiLangUtils;

const {metaUtil} = fa_utils;

const {SAVE, BATCH_ALTER, EXIT_TRANFER} = constants.LIST_BTNS.HEAD;
const pageCode = constants.PAGE_CODE.LIST;
const tableId = constants.AREA.LIST.GRID_AREA; //表格区
const destDataSource = constants.destDataSource;

export default function (props, id) {
    const that = this;
    switch (id) {
        //保存
        case SAVE:
            doBatchSave(that);
            break;

        //批改
        case BATCH_ALTER:
            doBatchAlter(that);
            break;

        //退出转单
        case EXIT_TRANFER:
            doExitTranfer.call(that);
            break;

        default:
            break;
    }
}

//保存
function doBatchSave(that) {
    // 获取选中的行
    let checkedRows = that.props.cardTable.getCheckedRows(tableId);
    if (!checkedRows || checkedRows.length < 1) {
        /* 国际化处理： 请选中需要保存的数据！*/
        showMessage(that.props, {content: getMultiLangByID('201201512A-000002'), color: 'warning'});
        return;
    }
    //校验 如果校验不通过直接返回
    const valid = batchSaveBeforeCheck(that, checkedRows);
    if (!valid) {
        return;
    }

    //组装提交数据：按照卡片的保存
    let dataForSave = fetchDataForSave(that);
    if (!dataForSave) {
        return;
    }

    if (!dataForSave.heads.length) {
        /* 国际化处理： 没有需要保存的卡片 */
        showMessage(that.props, {content: getMultiLangByID('201201512A-000003'), color: 'info'});
        return;
    }

    ajax({
        url: constants.URL.insert,
        data: dataForSave,
        success: (res) => {
            let {success, data: dataSaveBack} = res;
            if (success && dataSaveBack) {
                batchSaveAfter(that, dataForSave, dataSaveBack);
            }
        },
        error: (err) => {
            showErrorMessageByRes(that.props, err);
        }
    });
}

function batchSaveAfter(that, dataForSave, dataSaveBack) {
    let dataUpdated = [];//后台已经保存成功的数据，需要更新到界面上
    let budget = false; //预算控制标志
    let newassetValidate = false;//新增资产审批单校验标志
    let otherValidate = false;//其他校验异常标志
    let userjson = null;
    //循环遍历返回数据，看是否有需要预警处理的vo 或者 资产入账价值（本币原值）大于新增资产审批单申请金额的提示信息
    for (let i in dataSaveBack) {
        let d = dataSaveBack[i];
        if (d.userjson && d.userjson.BudgetMessage) {
            budget = true;
            userjson = d.userjson;
            break;
        } else if (d.userjson && d.userjson.NewAssetAprvMsg) {
            newassetValidate = true;
            userjson = d.userjson;
            break;
        } else if (d.userjson && d.userjson.validateMsg) {
            otherValidate = true;
            userjson = d.userjson;
            break;
        } else {
            dataUpdated[i] = dataSaveBack[i];
        }
    }
    dataUpdated.forEach((row, index) => {
        let assetAllData = [];
        const heads = row.heads;
        for (let headOne of heads) {
            assetAllData = assetAllData.concat(headOne[tableId].rows);
        }

        if (assetAllData.length > 0) {
            const realIndex = dataForSave.tableIndexs[index];
            updateAfterSave(that, assetAllData, realIndex);
        }
    });
    if (budget) {
        const realIndex = dataForSave.tableIndexs[userjson.sequence] + 1;
        let noFooter = false;
        userjson.BudgetType && userjson.BudgetType !== 'Alarm' && (noFooter = true);
        that.props.modal.show('budgetControl', {
            title: getMultiLangByID('201201512A-000006')/* 国际化处理： 提示 */,
            content: getMultiLangByID('201201512A-000053', {num: realIndex}) + userjson.BudgetMessage,
            noFooter,
            beSureBtnClick: () => {
                //预警控制确认处理
                let dataForSave = fetchDataForSave(that);
                if (!dataForSave) {
                    return;
                }
                dataForSave.userjson = {'SkipCodes': 'Y'};
                batchSaveAjax(that, dataForSave);
            }
        });
    } else if (newassetValidate) {
        const realIndex = dataForSave.tableIndexs[userjson.sequence] + 1;
        that.props.modal.show('budgetControl', {
            title: getMultiLangByID('201201512A-000006')/* 国际化处理： 提示 */,
            content: getMultiLangByID('201201512A-000053', {num: realIndex}) + userjson.NewAssetAprvMsg,
            beSureBtnClick: () => {
                let dataForSave = fetchDataForSave(that);
                if (!dataForSave) {
                    return;
                }
                dataForSave.userjson = {'newasset_fa81_feedback': 'Y'};
                batchSaveAjax(that, dataForSave);
            }
        });
    } else if (otherValidate) {
        const realIndex = dataForSave.tableIndexs[userjson.sequence] + 1;
        showMessage(that.props, {
            color: 'danger',
            content: getMultiLangByID('201201512A-000053', {num: realIndex}) + userjson.validateMsg
        });
    } else {
        showMessage(that.props, MsgConst.Type.SaveSuccess);
    }
}

//批量保存的ajax请求
function batchSaveAjax(that, data) {
    ajax({
        url: constants.URL.insert,
        data,
        success: (res) => {
            let {success, data: dataSaveBack} = res;
            if (success && dataSaveBack) {
                batchSaveAfter(that, data, dataSaveBack);
            }
        },
        error: (err) => {
            showErrorMessageByRes(that.props,err);
        }
    });
}

//删除还未保存的行
function doDeleteLineUnsaved(that, index) {
    //更新缓存索引
    let assetDataMap = that.assetDataMap;
    let lastIndex = 0;
    for (let i in assetDataMap) {
        if (i > index) {
            assetDataMap[i - 1] = assetDataMap[i];
        }
        lastIndex = i;
    }

    //删除最后一个
    delete assetDataMap[lastIndex];

    //解锁与该行关联的上游单据
    unlockBillSourceOnCancel.call(that, index);

    //删除表格行
    that.props.cardTable.delRowsByIndex(tableId, index);
}

//取得需要保存的数据
function fetchDataForSave(that) {
    let data = null;
    // 获取选中的行
    let checkedRows = that.props.cardTable.getCheckedRows(tableId);
    if (!checkedRows || checkedRows.length < 1) {
        return data;
    }
    //只是过滤未保存的
    let indexs = checkedRows.filter((row) => {
        return !(row.data.values.pk_card && row.data.values.pk_card.value);
    }).map((row) => row.index);
    let assetDataMap = that.assetDataMap;
    let heads = [];
    //同步其他账簿数据
    for (let i of indexs) {
        let assetvos = assetDataMap[i];
        that.syncDataForCommit(assetvos);
        heads.push({
            pageid: pageCode,
            model: {
                areacode: tableId,
                areaType: 'table',
                rows: assetvos
            }
        });

        //缓存使用部门，用于保存后恢复 这里缓存的数据实际上不是保存后的数据，但是保存前后的显示是一致的
        // 这是由于后台部门不好处理，暂时先用这种方式
        that.usedeptCache[i] = that.getMainAccbookData(assetvos).values.pk_usedept;
    }

    if (!heads.length) {
        return data;
    }

    //组装提交数据：按照卡片的保存
    data = {
        pageid: pageCode,
        templateid: that.templateid,
        userjson: {},
        heads,
        bodysMap: {},
        tableIndexs: indexs/* 数据在 table 中的行号*/
    };

    return data;
}

//删除已经保存的行
function doDeleteLineSaved(that, index) {
    //先调用卡片删除接口删除卡片
    const pk = that.props.cardTable.getValByKeyAndIndex(tableId, index, 'pk_card').value;
    const ts = that.props.cardTable.getValByKeyAndIndex(tableId, index, 'ts').value;

    if (pk) {
        const data = {
            pks: pk,
            tss: ts
        };
        ajax({
            url: constants.URL.delete_card,
            data,
            success: (res) => {
                let {success, data} = res;
                if (success) {
                    //删除表格 及 缓存中该行的数据
                    doDeleteLineUnsaved(that, index);
                } else {
                    /*国际化处理：删除失败*/
                    showMessage(that.props, {type: MsgConst.Type.DeleteFailed});
                }
            },
            error: (err) => {
                showErrorMessageByRes(that.props, err);
            }
        });
    }
}

//单个保存
function doSingleSave(that, index) {
    let assetvos = that.assetDataMap[index];
    //同步其他账簿数据
    that.syncDataForCommit(assetvos);

    const valid = saveBeforeCheck(that, [index]);
    if (!valid) {
        return;
    }

    //组装提交数据：按照卡片的保存
    let dataForSave = {
        pageid: pageCode,
        templateid: that.templateid,
        userjson: {},
        heads: [
            {
                pageid: pageCode,
                model: {
                    areacode: tableId,
                    areaType: 'table',
                    rows: assetvos
                }
            }
        ],
        bodysMap: {},
        tableIndexs: [index]
    };

    //暂存使用部门数据，用户保存后恢复
    that.usedeptCache[index] = that.getMainAccbookData(assetvos).values.pk_usedept;

    singleSaveAjax(that, dataForSave);
}

//单个保存的 ajax 请求
function singleSaveAjax(that, data) {
    ajax({
        url: constants.URL.insert,
        data,
        success: (res) => {
            let {success, data: dataSaveBack} = res;
            if (success && dataSaveBack) {
                singleSaveAfter(that, data, dataSaveBack);
            }
        },
        error: (err) => {
            showErrorMessageByRes(that.props, err);
        }
    });
}

//单个保存返回处理
function singleSaveAfter(that, dataForSave, dataSaveBack) {
    let userjson = dataSaveBack[0].userjson;
    let budget = userjson && userjson.BudgetMessage;//预算异常
    let newassetValidate = userjson && userjson.NewAssetAprvMsg;//新增资产审批单异常
    let otherValidate = userjson && userjson.validateMsg;//其他保存异常
    if (budget) {
        let noFooter = false;
        userjson.BudgetType && userjson.BudgetType !== 'Alarm' && (noFooter = true);
        that.props.modal.show('budgetControl', {
            title: getMultiLangByID('201201512A-000006')/* 国际化处理： 提示 */,
            content: userjson.BudgetMessage,
            noFooter,
            beSureBtnClick: () => {
                let dataForSave2 = Object.assign({}, dataForSave);
                dataForSave2.userjson = {SkipCodes: 'Y'};
                singleSaveAjax(that, dataForSave2);
            }
        });
    } else if (newassetValidate) {
        that.props.modal.show('budgetControl', {
            title: getMultiLangByID('201201512A-000006')/* 国际化处理： 提示 */,
            content: userjson.NewAssetAprvMsg,
            beSureBtnClick: () => {
                let dataForSave2 = Object.assign({}, dataForSave);
                dataForSave2.userjson = {'newasset_fa81_feedback': 'Y'};
                singleSaveAjax(that, dataForSave2);
            }
        });
    } else if (otherValidate) {
        showMessage(that.props, {color: 'danger', content: otherValidate});
    } else {
        showMessage(that.props, MsgConst.Type.SaveSuccess);
        dataSaveBack.forEach((row, index) => {
            let assetAllData = [];
            const heads = row.heads;
            for (let headOne of heads) {
                assetAllData = assetAllData.concat(headOne[tableId].rows);
            }

            if (assetAllData.length > 0) {
                const realIndex = dataForSave.tableIndexs[index];
                updateAfterSave(that, assetAllData, realIndex);
            }
        });
    }
}

function updateAfterSave(that, assetvos, index) {
    //会写使用部门字段
    let pk_usedept = that.usedeptCache[index];
    assetvos.map((assetvo) => {
        assetvo.values.pk_usedept = pk_usedept;
    });

    //得到主账簿数据
    const mainAccbookData = that.getMainAccbookData(assetvos);
    let status = 2;
    if (mainAccbookData) {
        if (mainAccbookData.values.pk_card.value) {
            status = 1;
        }

        //来源单据主表的主键
        let source_bill_head_pk = mainAccbookData.values.pk_bill_src.value;

        //来源单据子表的主键
        let source_bill_body_pk = mainAccbookData.values.pk_bill_b_src.value;
        let bill_source = mainAccbookData.values.bill_source.value;
        if (bill_source === '4A00') {
            //设备卡片 单独处理
            source_bill_body_pk = mainAccbookData.values.pk_bill_src.value;
        }

        //更新上游单据缓存
        let sourceBillVO = that.sourceBill.filter((bill) => {
            return bill['sourceHeadPk'] === source_bill_head_pk;
        })[0];
        // 建卡方式： 0 - 按表体行建卡 ；1 - 按项目合并建卡 ；2 - 按数量拆分建卡；3 - 按整单建卡；
        if (sourceBillVO && ['1', '3'].includes(sourceBillVO['createCardStyle'])) {// 1 或 3
            //更新全部子表的缓存
            //这里进行了简便处理保证了数据的正确性，如果上游还有未生成卡片的子表记录，可通过再次查询而得到
            sourceBillVO['sourceBodyPks'].map((body_pk) => {
                that.props.transferTable.savePk(dataSource, body_pk);
            });
        } else {
            that.props.transferTable.savePk(dataSource, source_bill_body_pk);
        }


        //更新缓存数据
        that.assetDataMap[index] = assetvos;

        //更新表格数据
        that.props.cardTable.updateDataByIndexs(tableId, [
            {
                index: index,
                data: {status, values: mainAccbookData.values}
            }
        ]);
        //设置该行不可编辑
        that.props.cardTable.setEditableByIndex(tableId, index, 0, false);

        //解锁与该行关联的上游单据
        unlockBillSource.call(that, source_bill_head_pk);
    }
}

//批改
function doBatchAlter(that) {
    let changeData = that.props.cardTable.getTableItemData(tableId);
    const field = changeData.batchChangeKey;
    // let value = changeData.batchChangeValue;
    let index = changeData.batchChangeIndex;
    // let display = changeData.batchChangeDisplay;

    //获取字段类型
    let item = metaUtil.getMetaItemByField(that.props, tableId, field);
    changeData.batchChangeFieldType = item.itemtype;
    changeData.batchChangeIndex = changeData.batchChangeIndex + "";


    //不支持批改的字段
    const fieldsUnSupported = ['asset_code', 'card_code', 'bar_code'];
    if (fieldsUnSupported.includes(field)) {
        return;
    }

    //同步多账簿数据
    syncAccbooksData(that, index, [field]);

    //3、组织数据进行提交， 到后台计算关联关系
    let heads = [];
    let assetDataMap = that.assetDataMap;
    for (let i in assetDataMap) {
        let assetvos = assetDataMap[i];
        const mainAccbook = that.getMainAccbook(assetvos);
        const userjson = {
            current_accbook: mainAccbook,
            fromAccbookChange: false,
            editStyle: 'table', //编辑方式：主要用于编辑后事件的多使用部门处理
            attrcode: field
        };
        heads.push({
            pageid: pageCode,
            model: {
                areacode: tableId,
                areaType: 'table',
                rows: assetvos
            },
            userjson: JSON.stringify(userjson)
        });
    }

    let data = {
        pageid: pageCode,
        templateid: that.templateid,
        userjson: {
            changeData
        },
        heads,
        bodysMap: {}
    };

    if (!heads.length) {//如果没有批改的数据，直接返回
        return;
    }

    ajax({
        url: constants.URL.batchalter,
        data,
        success: (res) => {
            let {success, data} = res;
            if (success) {
                batchAlterBack(that, data);
            }
        },
        error: (err) => {
            showErrorMessageByRes(that.props, err);
            //清空该列的值
            let {index} = that.props.cardTable.getClickRowIndex(tableId);
            let batchCellVal = that.props.cardTable.getValByKeyAndIndex(tableId, index, field);
            batchCellVal = {
                display: '',
                value: '',
                scale: batchCellVal.scale
            };
            that.props.cardTable.setColValue(tableId, field, batchCellVal);
        }
    });
}

//不能批改的行
function unBatchIndexs(that) {
    let assetDataMap = that.assetDataMap;
    let rowIndexSaved = [];

    for (let i in assetDataMap) {
        let assetvos = assetDataMap[i];
        //已经保存的数据不支持批改
        const mainAccbookData = that.getMainAccbookData(assetvos);
        if (mainAccbookData && mainAccbookData.values.pk_card && mainAccbookData.values.pk_card.value) {
            rowIndexSaved.push(i);
        }
    }

    return rowIndexSaved;
}

/**
 * 同步个账簿之间的数据
 * @param that
 * @param index 行号
 * @param fields 需要同步的字段
 */
function syncAccbooksData(that, index, fields) {
    let assetvos = that.assetDataMap[index];
    if(assetvos.length === 1) {
        return;
    }
    //得到主账簿数据
    let mainAccbookData = that.getMainAccbookData(assetvos);

    //业务字段直接更新到所有账簿， 账簿字段只更新到主账簿
    fields.forEach((f) => {
        if (that.busiFields.includes(f)) {//把业务字段同步到所有账簿
            assetvos.forEach((assetvo) => {
                assetvo.values[f] = mainAccbookData.values[f];
            });
        }
    });
}


//批改返回
function batchAlterBack(that, data) {
    const tableData = [];
    // data is array
    for (let i = 0; i < data.length; i++) {
        const heads = data[i]['toUIObject'].heads;

        let assetAllData = [];
        if (heads) {
            heads.forEach((head) => {
                if (head[tableId] && head[tableId].rows && head[tableId].rows.length > 0) {
                    assetAllData = assetAllData.concat(head[tableId].rows);
                }
            });
        }
        let assetvos = assetAllData;

        // console.log('批改返回数据， 第 i 行：', i);
        // console.log('批改返回数据， 第i行数据：', assetAllData);

        //得到主账簿数据
        const mainAccbookData = that.getMainAccbookData(assetvos);
        if (mainAccbookData) {
            tableData.push(mainAccbookData);
        } else {//主账簿为空时，表示当前【类别】还为空，此时 assetvos.length=1
            tableData.push(assetvos[0]);
        }
        that.assetDataMap[i] = assetvos;
    }

    //设置表格数据
    that.props.cardTable.setTableData(tableId, {rows: tableData}, () => {

    });
}

//退出转单
function doExitTranfer() {
    let backToSource = () => {
        //减锁所有来源单据
        if (this.sourceBillHeadPksLocked.size) {
            lockrequest.call(this, [...this.sourceBillHeadPksLocked]);
        }

        //返回来源单据查询界面
        this.props.pushTo('/source', {
            pagecode: allTransferPageCode
        });
    };

    //如果有未处理完的单据给出提示
    let pk_cards = this.props.cardTable.getColValue(tableId, 'pk_card');
    let unHanderNum = 0;
    if (pk_cards && pk_cards.length) {
        pk_cards.map((pk) => {
            pk && !pk.value && unHanderNum++;
        });
    }
    if(unHanderNum) {
        showConfirm.call(this, this.props, {
            type: MsgConst.Type.Back,
            beSureBtnClick: backToSource
        });
    } else {
        backToSource();
    }
}


function batchSaveBeforeCheck(that, rows) {
    const indexs = rows.map((row) => row.index);
    return saveBeforeCheck(that, indexs);
}

function saveBeforeCheck(that, indexs) {
    //获取表格的必输项字段
    const fieldsRequired = metaUtil.getRequiredFieldByArea(that.props, tableId);

    let errMsg = [];
    let valid = true;
    indexs.map((index) => {
        //获取当前行的数据
        const assetvos = that.assetDataMap[index];
        const emptyFields = new Set();
        let validOne = true;
        for (let assetvo of assetvos) {
            for (let field of fieldsRequired) {
                if (!assetvo.values[field].value) {
                    valid = false;
                    validOne = false;
                    emptyFields.add(field);
                }
            }
        }

        if (!validOne) {
            const emptyFieldsLabel = metaUtil.getFieldLabels(that.props, tableId, emptyFields);
            /**第x行字段不能为空 */
            errMsg.push(
                getMultiLangByID('201201512A-000021', {
                    num: index + 1,
                    fields: [...emptyFieldsLabel.map(field => '[' + field + ']')].join(', ')
                })
            );
        }
    });
    if (!valid) {
        if (errMsg && errMsg.length === 1) {
            toast({content: errMsg[0], color: 'warning'});
        } else {
            toast({
                duration: 'infinity',
                title: getMultiLangByID('facommon-000014'), /* 国际化处理： 保存失败！ */
                color: 'danger',
                content: getMultiLangByID('facommon-000015'), /* 国际化处理： 下列字段值不能为空: */
                groupOperation: true,
                groupOperationMsg: errMsg,
                TextArr: [getMultiLangByID('amcommon-000005'),
                    getMultiLangByID('amcommon-000006'),
                    getMultiLangByID('amcommon-000007')] /* 国际化处理： ['展开', '收起', '关闭'] */
            });
        }
    }

    return valid;
}


/**
 * 点击取消按钮时解锁
 */
function unlockBillSourceOnCancel(index) {
    let that = this;

    //当前行
    let currRow = this.props.cardTable.getRowsByIndexs(tableId, index);
    currRow = currRow[0]; //实际上只有一行

    //1、取出需要解锁的来源单据主键
    let rows = this.props.cardTable.getVisibleRows(tableId);
    //过滤未保存的行,取出未保存行的来源单据主键
    let sourceBillUnSaved = new Set();
    rows.map((row) => {
        //排除当前行
        if (row.rowid !== currRow.rowid && (!row.values.pk_card || !row.values.pk_card.value)) {
            sourceBillUnSaved.add(row.values.pk_bill_src.value);
        }
    });

    //取出需要减锁的主键
    let pk4unlock = [...this.sourceBillHeadPksLocked].filter((pk) => {
        return !sourceBillUnSaved.has(pk);
    });

    if (!pk4unlock.length) {
        return;
    }

    lockrequest.call(this, pk4unlock).then(() => {
        //减锁成功后更新未解锁主键列表
        that.sourceBillHeadPksLocked = sourceBillUnSaved;
    });
}

/**
 * 加锁，解锁来源单据
 */
function unlockBillSource(source_bill_head_pk) {
    let that = this;
    //1、取出需要解锁的来源单据主键
    let rows = this.props.cardTable.getVisibleRows(tableId);
    //过滤未保存的行,取出未保存行的来源单据主键
    let sourceBillUnSaved = new Set();
    rows.map((row) => {
        if (!row.values.pk_card || !row.values.pk_card.value) {
            sourceBillUnSaved.add(row.values.pk_bill_src.value);
        }
    });

    //取出需要减锁的主键
    let pk4unlock = [...this.sourceBillHeadPksLocked].filter((pk) => {
        return !sourceBillUnSaved.has(pk);
    });

    if (!pk4unlock.length) {
        return;
    }

    lockrequest.call(this, pk4unlock).then(() => {
        //减锁成功后更新未解锁主键列表
        that.sourceBillHeadPksLocked = sourceBillUnSaved;
    });
}

/**
 * 加解锁请求
 * @param pks 加减锁单据主键
 * @param lockflag 加减锁标志
 * @param async ajax同步异步请求参数
 * @returns {Promise<any>}
 */
function lockrequest(pks, lockflag = 'unlock', async = true) {
    let cuserid = getContext(loginContextKeys.userId, destDataSource);
    let dataSourceOfServer = getContext(loginContextKeys.dataSourceCode, destDataSource);

    let param = {
        allpks: pks,
        msgMap: {
            usrid: cuserid,
            lockflag,
            dSource: dataSourceOfServer
        }
    };

    let promise = new Promise(function (resolve, reject) {
        ajax({
            url: constants.URL.lock,
            data: param,
            async,
            success: (res) => {
                resolve();
            },
            error: (res) => {
                if (res && res.message) {
                    toast({content: res.message, color: 'danger'});
                }
                reject();
            }
        });
    });

    return promise;
}

export {doSingleSave, doDeleteLineUnsaved, doDeleteLineSaved, lockrequest};

/*Hm9gUKDDwtNjV7Mk8onAzgXlk2sN3YqGeiNBfMPmEAaQ5tb/cjXQzjs3lVWuDzNj*/